// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifndef __PLANETARYCOMMON_H_
#define __PLANETARYCOMMON_H_

// Zone-name defines
#define ZONE_UP 0
#define ZONE_DOWN 1
#define ZONE_FRONT 2
#define ZONE_BACK 3
#define ZONE_LEFT 4
#define ZONE_RIGHT 5

#include <OgreGpuProgram.h>
#include <OgreTechnique.h>
#include <OgrePass.h>

namespace Ogre
{
	/// Simple list of possible neighbours (given as cardinal directions - north, south, etc)
	enum NEIGHBOUR
	{
		NORTH = 0,
		SOUTH = 1,
		WEST = 2,
		EAST = 3
	};

	/// Translates the neighbour: if ZONE_EAST,and SOUTH is passed, the value returned is the relation the child zone has to ZONE_EAST
	inline NEIGHBOUR translateNeighbour(unsigned int zone, NEIGHBOUR n)
	{
		static NEIGHBOUR table[6][4] = {{ SOUTH, NORTH, NORTH, NORTH }, // ZONE_UP       |
						{ SOUTH, NORTH, SOUTH, SOUTH }, // ZONE_DOWN     |
						{ SOUTH, NORTH, EAST, WEST },   // ...
						{ SOUTH, NORTH, WEST, EAST },
						{ WEST, WEST, WEST, WEST },
						{ EAST, EAST, EAST, EAST } };
				
		return table[zone][n];
	}
	
	/**
	* Converts cube-coordinates into sphere-coordinates.
	* Maths are based on this:
	* http://mathproofs.blogspot.com/2005/07/mapping-cube-to-sphere.html
	*/
	inline Vector3 cubeToSphereCoords(float x, float y, float z)
	{
		Vector3 res;
		res.x = x * sqrtf(1.0f - y * y * 0.5f - z * z * 0.5f + y * y * z * z / 3.0f);
		res.y = y * sqrtf(1.0f - z * z * 0.5f - x * x * 0.5f + z * z * x * x / 3.0f);
		res.z = z * sqrtf(1.0f - x * x * 0.5f - y * y * 0.5f + x * x * y * y / 3.0f);
		return res;
	}

	inline String zoneToStr(unsigned int zone)
	{
		switch(zone)
		{
		case ZONE_UP:
			return String("ZONE_UP");
		case ZONE_DOWN:
			return String("ZONE_DOWN");
		case ZONE_LEFT:
			return String("ZONE_LEFT");
		case ZONE_RIGHT:
			return String("ZONE_RIGHT");
		case ZONE_FRONT:
			return String("ZONE_FRONT");
		case ZONE_BACK:
			return String("ZONE_BACK");	
		default:
			return String("ZONE_UNKNOWN");
		}
	}
	
	inline String relationToStr(unsigned int relation)
	{
		switch(relation)
		{
		case NORTH:
			return String("NORTH");
		case SOUTH:
			return String("SOUTH");
		case EAST:
			return String("EAST");
		case WEST:
			return String("WEST");
		default:
			return String("UNKNOWN_RELATION");
		}
	}
}

#endif
